bitkeeper revision 1.959.1.5 (40d04b7b7MkMcLlaSNJov9qsPAZ9tg)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Wed, 16 Jun 2004 13:30:35 +0000 (13:30 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Wed, 16 Jun 2004 13:30:35 +0000 (13:30 +0000)
Remove vdisk code.

.rootkeys
tools/examples/xc_vd_tool.py [deleted file]
tools/examples/xm_vd_tool.py [deleted file]
tools/xenctl/lib/vdisk.py [deleted file]
tools/xenctl/setup.py
tools/xenmgr/lib/XendDomain.py
tools/xenmgr/lib/XendDomainInfo.py
tools/xenmgr/lib/XendVdisk.py [deleted file]
tools/xenmgr/lib/server/SrvRoot.py
tools/xenmgr/lib/server/SrvVdisk.py [deleted file]
tools/xenmgr/lib/server/SrvVdiskDir.py [deleted file]

index a20dd32e1fe0d46d8166759bc204e4a89fb73a1d..936353def586a8efeeb1c7088e85711e30163c25 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 401d7e16NpnVrFSsR7lKKKfTwCYvWA tools/examples/xc_dom_control.py
 401d7e16RJj-lbtsVEjua6HYAIiKiA tools/examples/xc_dom_create.py
 403b7cf7J7FsSSoEPGhx6gXR4pIdZg tools/examples/xc_physinfo.py
-401d7e16X4iojyKopo_j63AyzYZd2A tools/examples/xc_vd_tool.py
 40c9c4684Wfg8VgMKtRFa_ULi2e_tQ tools/examples/xm_dom_control.py
 40c9c468pXANclL7slGaoD0kSrIwoQ tools/examples/xm_dom_create.py
-40c9c468QKoqBHjb5Qwrm60pNVcVng tools/examples/xm_vd_tool.py
 40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmdefaults
 3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
 40ab2cfawIw8tsYo0dQKtp83h4qfTQ tools/misc/fakei386xen
 40c9c468IienauFHQ_xJIcqnPJ8giQ tools/xenctl/lib/ip.py
 4059c6a0pnxhG8hwSOivXybbGOwuXw tools/xenctl/lib/tempfile.py
 3fbd4bd6GtGwZGxYUJPOheYIR7bPaA tools/xenctl/lib/utils.py
-40c9c468F36e06WH38kpYrD3JfXC0Q tools/xenctl/lib/vdisk.py
 4055ee44Bu6oP7U0WxxXypbUt4dNPQ tools/xenctl/setup.py
 40431ac64Hj4ixUnKmlugZKhXPFE_Q tools/xend/Makefile
 4055ad95Se-FqttgxollqOAAHB94zA tools/xend/lib/__init__.py
 40c9c46854nsHmuxHQHncKk5rAs5NA tools/xenmgr/lib/XendMigrate.py
 40c9c468M96gA1EYDvNa5w5kQNYLFA tools/xenmgr/lib/XendNode.py
 40c9c4686jruMyZIqiaZRMiMoqMJtg tools/xenmgr/lib/XendRoot.py
-40c9c468P75aHqyIE156JXwc-5W92A tools/xenmgr/lib/XendVdisk.py
 40c9c468xzANp6o2D_MeCYwNmOIUsQ tools/xenmgr/lib/XendVnet.py
 40c9c468x191zetrVlMnExfsQWHxIQ tools/xenmgr/lib/__init__.py
 40c9c468S2YnCEKmk4ey8XQIST7INg tools/xenmgr/lib/encode.py
 40c9c4694eu5759Dehr4Uhakei0EMg tools/xenmgr/lib/server/SrvNode.py
 40c9c469TaZ83ypsrktmPSHLEZiP5w tools/xenmgr/lib/server/SrvRoot.py
 40c9c469W3sgDMbBJYQdz5wbQweL0Q tools/xenmgr/lib/server/SrvServer.py
-40c9c469JlUVPkwGWZyVnqIsU8U6Bw tools/xenmgr/lib/server/SrvVdisk.py
-40c9c469sG8iuyxjVH3zKw8XOAyxtQ tools/xenmgr/lib/server/SrvVdiskDir.py
 40c9c469aq7oXrE1Ngqf3_lBqL0RoQ tools/xenmgr/lib/server/SrvVnetDir.py
 40c9c469Y_aimoOFfUZoS-4eV8gEKg tools/xenmgr/lib/server/__init__.py
 40c9c4692hckPol_EK0EGB16ZyDsyQ tools/xenmgr/lib/server/blkif.py
diff --git a/tools/examples/xc_vd_tool.py b/tools/examples/xc_vd_tool.py
deleted file mode 100755 (executable)
index 9184d35..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/usr/bin/env python
-
-import xenctl.utils, sys, re, string
-
-def usage():
-
-    print >>sys.stderr,"""
-Usage: %s command <params>
-
-  initialise [dev] [[ext_size]] - init. a physcial partition to store vd's
-  create [size] [[expiry]]      - allocate a vd of specified size (and expiry)
-  enlarge [vdid] [extra_size]   - enlarge a specified vd by some amount
-  delete [vdid]                 - delete a vd
-  import [filename] [[expiry]]  - create a vd and populate w/ image from file
-  export [vdid] [filename]      - copy vd's contents to a file
-  setexpiry [vdid] [[expiry]]   - update the expiry time for a vd
-  list                          - list all the unexpired virtual disks  
-  undelete [vdid] [[expiry]]    - attempts to recover an expired vd
-  freespace                     - print out the amount of space in free pool
-
-notes:
-  vdid      - the virtual disk's identity string
-  size      - measured in MB
-  expiry    - is the expiry time of the virtual disk in seconds from now
-               (0 = don't expire) 
-  device    - physical partition to 'format' to hold vd's. e.g. hda4
-  ext_size  - extent size (default 64MB)
-""" % sys.argv[0]  
-
-if len(sys.argv) < 2: 
-    usage()
-    sys.exit(-1)
-
-rc=''
-src=''
-expiry_time = 0
-cmd = sys.argv[1]
-
-if cmd == 'initialise':
-
-    dev = sys.argv[2]
-
-    if len(sys.argv) > 3:
-       extent_size = int(sys.argv[3])
-    else:
-       print """No extent size specified - using default size of 64MB"""
-       extent_size = 64
-
-    print "Formatting for virtual disks"
-    print "Device: " + dev
-    print "Extent size: " + str(extent_size) + "MB"
-
-    rc = xenctl.utils.vd_format(dev, extent_size)
-
-elif cmd == 'create':
-    size = int(sys.argv[2])
-    
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-
-    print "Creating a virtual disk"
-    print "Size: %d" % size
-    print "Expiry time (seconds from now): %d" % expiry_time
-
-    src = xenctl.utils.vd_create(size, expiry_time)
-
-elif cmd == 'enlarge':
-
-    id = sys.argv[2]
-
-    extra_size = int(sys.argv[3])
-
-    rc = xenctl.utils.vd_enlarge(id, extra_size)
-
-elif cmd == 'delete':
-
-    id = sys.argv[2]
-
-    print "Deleting a virtual disk with ID: " + id
-
-    rc = xenctl.utils.vd_delete(id)
-
-elif cmd == 'import':
-
-    file = sys.argv[2]
-    
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-
-    print "Allocate new virtual disk and populate from file : %s" % file
-
-    print xenctl.utils.vd_read_from_file(file, expiry_time)
-
-elif cmd == 'export':
-
-    id = sys.argv[2]
-    file = sys.argv[3]
-
-    print "Dump contents of virtual disk to file : %s" % file
-
-    rc = xenctl.utils.vd_cp_to_file(id, file )
-
-elif cmd == 'setexpiry':
-
-    id = sys.argv[2]
-
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-
-    print "Refreshing a virtual disk"
-    print "Id: " + id
-    print "Expiry time (seconds from now [or 0]): " + str(expiry_time)
-
-    rc = xenctl.utils.vd_refresh(id, expiry_time)
-
-elif cmd == 'list':
-    print 'ID    Size(MB)      Expiry'
-
-    for vbd in xenctl.utils.vd_list():
-        vbd['size_mb'] = vbd['size'] / 2048
-        vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never'
-        print '%(vdisk_id)-4s  %(size_mb)-12d  %(expiry)s' % vbd
-
-elif cmd == 'freespace':
-
-    print xenctl.utils.vd_freespace()
-
-elif cmd == 'undelete':
-
-    id = sys.argv[2]
-
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-   
-    if xenctl.utils.vd_undelete(id, expiry_time):
-       print "Undelete operation failed for virtual disk: " + id
-    else:
-       print "Undelete operation succeeded for virtual disk: " + id
-
-else:
-    usage()
-    sys.exit(-1)
-
-
-if src != '':  
-    print "Returned virtual disk id is : %s" % src
-
-if rc != '':
-    print "return code %d" % rc
-
-
-
diff --git a/tools/examples/xm_vd_tool.py b/tools/examples/xm_vd_tool.py
deleted file mode 100755 (executable)
index 7207a59..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import re
-import string
-
-from xenctl import vdisk
-
-def usage():
-
-    print >>sys.stderr,"""
-Usage: %s command <params>
-
-  initialise [dev] [[ext_size]] - init. a physcial partition to store vd's
-  create [size] [[expiry]]      - allocate a vd of specified size (and expiry)
-  enlarge [vdid] [extra_size]   - enlarge a specified vd by some amount
-  delete [vdid]                 - delete a vd
-  import [filename] [[expiry]]  - create a vd and populate w/ image from file
-  export [vdid] [filename]      - copy vd's contents to a file
-  setexpiry [vdid] [[expiry]]   - update the expiry time for a vd
-  list                          - list all the unexpired virtual disks  
-  undelete [vdid] [[expiry]]    - attempts to recover an expired vd
-  freespace                     - print out the amount of space in free pool
-
-notes:
-  vdid      - the virtual disk's identity string
-  size      - measured in MB
-  expiry    - is the expiry time of the virtual disk in seconds from now
-               (0 = don't expire) 
-  device    - physical partition to 'format' to hold vd's. e.g. hda4
-  ext_size  - extent size (default 64MB)
-""" % sys.argv[0]  
-
-if len(sys.argv) < 2: 
-    usage()
-    sys.exit(-1)
-
-rc=''
-src=''
-expiry_time = 0
-cmd = sys.argv[1]
-
-if cmd == 'initialise':
-
-    dev = sys.argv[2]
-
-    if len(sys.argv) > 3:
-       extent_size = int(sys.argv[3])
-    else:
-       print """No extent size specified - using default size of 64MB"""
-       extent_size = 64
-
-    print "Formatting for virtual disks"
-    print "Device: " + dev
-    print "Extent size: " + str(extent_size) + "MB"
-
-    rc = vdisk.vd_format(dev, extent_size)
-
-elif cmd == 'create':
-    size = int(sys.argv[2])
-    
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-
-    print "Creating a virtual disk"
-    print "Size: %d" % size
-    print "Expiry time (seconds from now): %d" % expiry_time
-
-    src = vdisk.vd_create(size, expiry_time)
-
-elif cmd == 'enlarge':
-
-    id = sys.argv[2]
-
-    extra_size = int(sys.argv[3])
-
-    rc = vdisk.vd_enlarge(id, extra_size)
-
-elif cmd == 'delete':
-
-    id = sys.argv[2]
-
-    print "Deleting a virtual disk with ID: " + id
-
-    rc = vdisk.vd_delete(id)
-
-elif cmd == 'import':
-
-    file = sys.argv[2]
-    
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-
-    print "Allocate new virtual disk and populate from file : %s" % file
-
-    print vdisk.vd_read_from_file(file, expiry_time)
-
-elif cmd == 'export':
-
-    id = sys.argv[2]
-    file = sys.argv[3]
-
-    print "Dump contents of virtual disk to file : %s" % file
-
-    rc = vdisk.vd_cp_to_file(id, file )
-
-elif cmd == 'setexpiry':
-
-    id = sys.argv[2]
-
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-
-    print "Refreshing a virtual disk"
-    print "Id: " + id
-    print "Expiry time (seconds from now [or 0]): " + str(expiry_time)
-
-    rc = vdisk.vd_refresh(id, expiry_time)
-
-elif cmd == 'list':
-    print 'ID    Size(MB)      Expiry'
-
-    for vbd in vdisk.vd_list():
-        vbd['size_mb'] = vbd['size'] / vdisk.VBD_SECTORS_PER_MB
-        vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never'
-        print '%(vdisk_id)-4s  %(size_mb)-12d  %(expiry)s' % vbd
-
-elif cmd == 'freespace':
-
-    print vdisk.vd_freespace()
-
-elif cmd == 'undelete':
-
-    id = sys.argv[2]
-
-    if len(sys.argv) > 3:
-       expiry_time = int(sys.argv[3])
-   
-    if vdisk.vd_undelete(id, expiry_time):
-       print "Undelete operation failed for virtual disk: " + id
-    else:
-       print "Undelete operation succeeded for virtual disk: " + id
-
-else:
-    usage()
-    sys.exit(-1)
-
-
-if src != '':  
-    print "Returned virtual disk id is : %s" % src
-
-if rc != '':
-    print "return code %d" % rc
-
-
-
diff --git a/tools/xenctl/lib/vdisk.py b/tools/xenctl/lib/vdisk.py
deleted file mode 100644 (file)
index 6c4d144..0000000
+++ /dev/null
@@ -1,944 +0,0 @@
-import os
-import re
-import socket
-import string
-import sys
-import tempfile
-import struct
-
-##### Module variables
-
-"""Location of the Virtual Disk management database.
-   defaults to /var/db/xen_vdisks.sqlite
-"""
-VD_DB_FILE = "/var/db/xen_vdisks.sqlite"
-
-"""VBD expertise level - determines the strictness of the sanity checking.
-  This mode determines the level of complaints when disk sharing occurs
-  through the current VBD mappings.
-   0 - only allow shared mappings if both domains have r/o access (always OK)
-   1 - also allow sharing with one dom r/w and the other r/o
-   2 - allow sharing with both doms r/w
-"""
-VBD_SAFETY_RR = 0
-VBD_SAFETY_RW = 1
-VBD_SAFETY_WW = 2
-
-VBD_SECTORS_PER_MB = 2048
-
-##### Module initialisation
-
-try:
-    # try to import sqlite (not everyone will have it installed)
-    import sqlite
-except ImportError:
-    # on failure, just catch the error, don't do anything
-    pass
-
-
-
-##### VBD-related Functions
-
-def blkdev_name_to_number(name):
-    """Take the given textual block-device name (e.g., '/dev/sda1',
-    'hda') and return the device number used by the OS. """
-
-    if not re.match( '/dev/', name ):
-        name = '/dev/' + name
-        
-    return os.stat(name).st_rdev
-
-# lookup_blkdev_partn_info( '/dev/sda3' )
-def lookup_raw_partn(partition):
-    """Take the given block-device name (e.g., '/dev/sda1', 'hda')
-    and return a dictionary { device, start_sector,
-    nr_sectors, type }
-        device:       Device number of the given partition
-        start_sector: Index of first sector of the partition
-        nr_sectors:   Number of sectors comprising this partition
-        type:         'Disk' or identifying name for partition type
-    """
-
-    if not re.match( '/dev/', partition ):
-        partition = '/dev/' + partition
-
-    drive = re.split( '[0-9]', partition )[0]
-
-    if drive == partition:
-        fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' )
-        line = readline(fd)
-        if line:
-            return [ { 'device' : blkdev_name_to_number(drive),
-                       'start_sector' : long(0),
-                       'nr_sectors' : long(line) * 2,
-                       'type' : 'Disk' } ]
-        return None
-
-    # determine position on disk
-    fd = os.popen( '/sbin/sfdisk -d ' + drive + ' 2>/dev/null' )
-
-    #['/dev/sda3 : start= 16948575, size=16836120, Id=83, bootable\012']
-    lines = readlines(fd)
-    for line in lines:
-        m = re.search( '^' + partition + '\s*: start=\s*([0-9]+), ' +
-                       'size=\s*([0-9]+), Id=\s*(\S+).*$', line)
-        if m:
-            return [ { 'device' : blkdev_name_to_number(drive),
-                       'start_sector' : long(m.group(1)),
-                       'nr_sectors' : long(m.group(2)),
-                       'type' : m.group(3) } ]
-    
-    return None
-
-def lookup_disk_uname( uname ):
-    """Lookup a list of segments for either a physical or a virtual device.
-    uname [string]:  name of the device in the format \'vd:id\' for a virtual
-                     disk, or \'phy:dev\' for a physical device
-    returns [list of dicts]: list of extents that make up the named device
-    """
-    ( type, d_name ) = string.split( uname, ':' )
-
-    if type == "phy":
-        segments = lookup_raw_partn( d_name )
-    elif type == "vd":
-       segments = vd_lookup( d_name )
-
-    return segments
-
-
-##### VD Management-related functions
-
-##### By Mark Williamson, <mark.a.williamson@intel.com>
-##### (C) Intel Research Cambridge
-
-# TODO:
-#
-# Plenty of room for enhancement to this functionality (contributions
-# welcome - and then you get to have your name in the source ;-)...
-#
-# vd_unformat() : want facilities to unallocate virtual disk
-# partitions, possibly migrating virtual disks of them, with checks to see if
-# it's safe and options to force it anyway
-#
-# vd_create() : should have an optional argument specifying a physical
-# disk preference - useful to allocate for guest doms to do RAID
-#
-# vd_undelete() : add ability to "best effort" undelete as much of a
-# vdisk as is left in the case that some of it has already been
-# reallocated.  Some people might still be able to recover some of
-# their data this way, even if some of the disk has disappeared.
-#
-# It'd be nice if we could wipe virtual disks for security purposes -
-# should be easy to do this using dev if=/dev/{zero,random} on each
-# extent in turn.  There could be another optional flag to vd_create
-# in order to allow this.
-#
-# Error codes could be more expressive - i.e. actually tell why the
-# error occurred rather than "it broke".  Currently the code avoids
-# using exceptions to make control scripting simpler and more
-# accessible to beginners - therefore probably should just use more
-# return codes.
-#
-# Enhancements / additions to the example scripts are also welcome:
-# some people will interact with this code mostly through those
-# scripts.
-#
-# More documentation of how this stuff should be used is always nice -
-# if you have a novel configuration that you feel isn't discussed
-# enough in the HOWTO (which is currently a work in progress), feel
-# free to contribute a walkthrough, or something more substantial.
-#
-
-
-def __vd_no_database():
-    """Called when no database found - exits with an error
-    """
-    print >> sys.stderr, "ERROR: Could not locate the database file at " + VD_DB_FILE
-    sys.exit(1)
-
-def readlines(fd):
-    """Version of readlines safe against EINTR.
-    """
-    import errno
-    
-    lines = []
-    while 1:
-        try:
-            line = fd.readline()
-        except IOError, ex:
-            if ex.errno == errno.EINTR:
-                continue
-            else:
-                raise
-        if line == '': break
-        lines.append(line)
-    return lines
-
-def readline(fd):
-    """Version of readline safe against EINTR.
-    """
-    while 1:
-        try:
-            return fd.readline()
-        except IOError, ex:
-            if ex.errno == errno.EINTR:
-                continue
-            else:
-                raise
-        
-
-def vd_format(partition, extent_size_mb):
-    """Format a partition or drive for use a virtual disk storage.
-    partition [string]: device file representing the partition
-    extent_size_mb [string]: extent size in megabytes to use on this disk
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        vd_init_db(VD_DB_FILE)
-    
-    if not re.match( '/dev/', partition ):
-        partition = '/dev/' + partition
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("select * from vdisk_part where partition = \'"
-               + partition + "\'")
-    row = cu.fetchone()
-
-    extent_size = extent_size_mb * VBD_SECTORS_PER_MB # convert megabytes to sectors
-    
-    if not row:
-        part_info = lookup_raw_partn(partition)[0]
-        
-        cu.execute("INSERT INTO vdisk_part(partition, part_id, extent_size) " +
-                   "VALUES ( \'" + partition + "\', "
-                   + str(blkdev_name_to_number(partition))
-                   + ", " + str(extent_size) + ")")
-
-
-        cu.execute("SELECT max(vdisk_extent_no) FROM vdisk_extents "
-                   + "WHERE vdisk_id = 0")
-        
-        max_id, = cu.fetchone()
-
-        if max_id != None:
-            new_id = max_id + 1
-        else:
-            new_id = 0
-
-        num_extents = part_info['nr_sectors'] / extent_size
-
-        for i in range(num_extents):
-            sql ="""INSERT INTO vdisk_extents(vdisk_extent_no, vdisk_id,
-                                              part_id, part_extent_no)
-                    VALUES ("""+ str(new_id + i) + ", 0, "\
-                               + str(blkdev_name_to_number(partition))\
-                               + ", " + str(num_extents - (i + 1)) + ")"
-            cu.execute(sql)
-
-    cx.commit()
-    cx.close()
-    return 0
-
-
-def vd_create(size_mb, expiry):
-    """Create a new virtual disk.
-    size_mb [int]: size in megabytes for the new virtual disk
-    expiry [int]: expiry time in seconds from now
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    size = size_mb * VBD_SECTORS_PER_MB
-
-    cu.execute("SELECT max(vdisk_id) FROM vdisks")
-    max_id, = cu.fetchone()
-    new_id = int(max_id) + 1
-
-    # fetch a list of extents from the expired disks, along with information
-    # about their size
-    cu.execute("""SELECT vdisks.vdisk_id, vdisk_extent_no, part_extent_no,
-                         vdisk_extents.part_id, extent_size
-                  FROM vdisks NATURAL JOIN vdisk_extents
-                                                  NATURAL JOIN vdisk_part
-                  WHERE expires AND expiry_time <= datetime('now')
-                  ORDER BY expiry_time ASC, vdisk_extent_no DESC
-               """)  # aims to reuse the last extents
-                     # from the longest-expired disks first
-
-    allocated = 0
-
-    if expiry:
-        expiry_ts = "datetime('now', '" + str(expiry) + " seconds')"
-        expires = 1
-    else:
-        expiry_ts = "NULL"
-        expires = 0
-
-    # we'll use this to build the SQL statement we want
-    building_sql = "INSERT INTO vdisks(vdisk_id, size, expires, expiry_time)" \
-                   +" VALUES ("+str(new_id)+", "+str(size)+ ", "              \
-                   + str(expires) + ", " + expiry_ts + "); "
-
-    counter = 0
-
-    while allocated < size:
-        row = cu.fetchone()
-        if not row:
-            print "ran out of space, having allocated %d meg of %d" % (allocated, size)
-            cx.close()
-            return -1
-        
-
-        (vdisk_id, vdisk_extent_no, part_extent_no, part_id, extent_size) = row
-        allocated += extent_size
-        building_sql += "UPDATE vdisk_extents SET vdisk_id = " + str(new_id) \
-                        + ", " + "vdisk_extent_no = " + str(counter)         \
-                        + " WHERE vdisk_extent_no = " + str(vdisk_extent_no) \
-                        + " AND vdisk_id = " + str(vdisk_id) + "; "
-
-        counter += 1
-        
-
-    # this will execute the SQL query we build to store details of the new
-    # virtual disk and allocate space to it print building_sql
-    cu.execute(building_sql)
-    
-    cx.commit()
-    cx.close()
-    return str(new_id)
-
-
-def vd_lookup(id):
-    """Lookup a Virtual Disk by ID.
-    id [string]: a virtual disk identifier
-    Returns [list of dicts]: a list of extents as dicts, containing fields:
-                             device : Linux device number of host disk
-                             start_sector : within the device
-                             nr_sectors : size of this extent
-                             type : set to \'VD Extent\'
-                             
-                             part_device : Linux device no of host partition
-                             part_start_sector : within the partition
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("-- types int")
-    cu.execute("""SELECT COUNT(*)
-                  FROM vdisks
-                  WHERE (expiry_time > datetime('now') OR NOT expires)
-                              AND vdisk_id = """ + id)
-    count, = cu.fetchone()
-
-    if not count:
-        cx.close()
-        return None
-
-    cu.execute("SELECT size from vdisks WHERE vdisk_id = " + id)
-    real_size, = cu.fetchone()
-  
-    # This query tells PySQLite how to convert the data returned from the
-    # following query - the use of the multiplication confuses it otherwise ;-)
-    # This row is significant to PySQLite but is syntactically an SQL comment.
-
-    cu.execute("-- types str, int, int, int")
-
-    # This SQL statement is designed so that when the results are fetched they
-    # will be in the right format to return immediately.
-    cu.execute("""SELECT partition, vdisk_part.part_id,
-                         round(part_extent_no * extent_size) as start,
-                         extent_size
-                         
-                  FROM vdisks NATURAL JOIN vdisk_extents
-                                             NATURAL JOIN vdisk_part
-                                                
-                  WHERE vdisk_extents.vdisk_id = """ + id
-               + " ORDER BY vdisk_extents.vdisk_extent_no ASC"
-               )
-
-    extent_tuples = cu.fetchall()
-
-    # use this function to map the results from the database into a dict
-    # list of extents, for consistency with the rest of the code
-    def transform ((partition, part_device, part_offset, nr_sectors)):
-        return {
-                 # the disk device this extent is on - for passing to Xen
-                 'device' : lookup_raw_partn(partition)[0]['device'],
-                 # the offset of this extent within the disk - for passing to Xen
-                 'start_sector' : long(part_offset + lookup_raw_partn(partition)[0]['start_sector']),
-                 # extent size, in sectors
-                 'nr_sectors' : nr_sectors,
-                 # partition device this extent is on (useful to know for xenctl.utils fns)
-                 'part_device' : part_device,
-                 # start sector within this partition (useful to know for xenctl.utils fns)
-                 'part_start_sector' : part_offset,
-                 # type of this extent - handy to know
-                 'type' : 'VD Extent' }
-
-    cx.commit()
-    cx.close()
-
-    extent_dicts = map(transform, extent_tuples)
-
-    # calculate the over-allocation in sectors (happens because
-    # we allocate whole extents)
-    allocated_size = 0
-    for i in extent_dicts:
-        allocated_size += i['nr_sectors']
-
-    over_allocation = allocated_size - real_size
-
-    # trim down the last extent's length so the resulting VBD will be the
-    # size requested, rather than being rounded up to the nearest extent
-    extent_dicts[len(extent_dicts) - 1]['nr_sectors'] -= over_allocation
-
-    return extent_dicts
-
-
-def vd_enlarge(vdisk_id, extra_size_mb):
-    """Create a new virtual disk.
-    vdisk_id [string]   :    ID of the virtual disk to enlarge
-    extra_size_mb  [int]:    size in megabytes to increase the allocation by
-    returns  [int]      :    0 on success, otherwise non-zero
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    extra_size = extra_size_mb * VBD_SECTORS_PER_MB
-
-    cu.execute("-- types int")
-    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + vdisk_id
-               + " AND (expiry_time > datetime('now') OR NOT expires)")
-    count, = cu.fetchone()
-
-    if not count: # no such vdisk
-        cx.close()
-        return -1
-
-    cu.execute("-- types int")
-    cu.execute("""SELECT SUM(extent_size)
-                  FROM vdisks NATURAL JOIN vdisk_extents
-                                         NATURAL JOIN vdisk_part
-                  WHERE vdisks.vdisk_id = """ + vdisk_id)
-
-    real_size, = cu.fetchone() # get the true allocated size
-
-    cu.execute("-- types int")
-    cu.execute("SELECT size FROM vdisks WHERE vdisk_id = " + vdisk_id)
-
-    old_size, = cu.fetchone()
-
-
-    cu.execute("--- types int")
-    cu.execute("""SELECT MAX(vdisk_extent_no)
-                  FROM vdisk_extents
-                  WHERE vdisk_id = """ + vdisk_id)
-
-    counter = cu.fetchone()[0] + 1 # this stores the extent numbers
-
-
-    # because of the extent-based allocation, the VD may already have more
-    # allocated space than they asked for.  Find out how much we really
-    # need to add.
-    add_size = extra_size + old_size - real_size
-
-    # fetch a list of extents from the expired disks, along with information
-    # about their size
-    cu.execute("""SELECT vdisks.vdisk_id, vdisk_extent_no, part_extent_no,
-                         vdisk_extents.part_id, extent_size
-                  FROM vdisks NATURAL JOIN vdisk_extents
-                                                  NATURAL JOIN vdisk_part
-                  WHERE expires AND expiry_time <= datetime('now')
-                  ORDER BY expiry_time ASC, vdisk_extent_no DESC
-               """)  # aims to reuse the last extents
-                     # from the longest-expired disks first
-
-    allocated = 0
-
-    building_sql = "UPDATE vdisks SET size = " + str(old_size + extra_size)\
-                   + " WHERE vdisk_id = " + vdisk_id + "; "
-
-    while allocated < add_size:
-        row = cu.fetchone()
-        if not row:
-            cx.close()
-            return -1
-
-        (dead_vd_id, vdisk_extent_no, part_extent_no, part_id, extent_size) = row
-        allocated += extent_size
-        building_sql += "UPDATE vdisk_extents SET vdisk_id = " + vdisk_id    \
-                        + ", " + "vdisk_extent_no = " + str(counter)         \
-                        + " WHERE vdisk_extent_no = " + str(vdisk_extent_no) \
-                        + " AND vdisk_id = " + str(dead_vd_id) + "; "
-
-        counter += 1
-        
-
-    # this will execute the SQL query we build to store details of the new
-    # virtual disk and allocate space to it print building_sql
-    cu.execute(building_sql)
-    
-    cx.commit()
-    cx.close()
-    return 0
-
-
-def vd_undelete(vdisk_id, expiry_time):
-    """Create a new virtual disk.
-    vdisk_id      [int]: size in megabytes for the new virtual disk
-    expiry_time   [int]: expiry time, in seconds from now
-    returns       [int]: zero on success, non-zero on failure
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-
-    if vdisk_id == '0': #  undeleting vdisk 0 isn't sane!
-        return -1
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("-- types int")
-    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + vdisk_id)
-    count, = cu.fetchone()
-
-    if not count:
-        cx.close()
-        return -1
-
-    cu.execute("-- types int")
-    cu.execute("""SELECT SUM(extent_size)
-                  FROM vdisks NATURAL JOIN vdisk_extents
-                                         NATURAL JOIN vdisk_part
-                  WHERE vdisks.vdisk_id = """ + vdisk_id)
-
-    real_size, = cu.fetchone() # get the true allocated size
-
-
-    cu.execute("-- types int")
-    cu.execute("SELECT size FROM vdisks WHERE vdisk_id = " + vdisk_id)
-
-    old_size, = cu.fetchone()
-
-    if real_size < old_size:
-        cx.close()
-        return -1
-
-    if expiry_time == 0:
-        expires = '0'
-    else:
-        expires = '1'
-
-    # this will execute the SQL query we build to store details of the new
-    # virtual disk and allocate space to it print building_sql
-    cu.execute("UPDATE vdisks SET expiry_time = datetime('now','"
-               + str(expiry_time) + " seconds'), expires = " + expires
-               + " WHERE vdisk_id = " + vdisk_id)
-    
-    cx.commit()
-    cx.close()
-    return 0
-
-
-
-
-def vd_list():
-    """Lists all the virtual disks registered in the system.
-    returns [list of dicts]
-    """
-    
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("""SELECT vdisk_id, size, expires, expiry_time
-                  FROM vdisks
-                  WHERE (NOT expires) OR expiry_time > datetime('now')
-               """)
-
-    ret = cu.fetchall()
-
-    cx.close()
-
-    def makedicts((vdisk_id, size, expires, expiry_time)):
-        return { 'vdisk_id' : str(vdisk_id), 'size': size,
-                 'expires' : expires, 'expiry_time' : expiry_time }
-
-    return map(makedicts, ret)
-
-
-def vd_refresh(id, expiry):
-    """Change the expiry time of a virtual disk.
-    id [string]  : a virtual disk identifier
-    expiry [int] : expiry time in seconds from now (0 = never expire)
-    returns [int]: zero on success, non-zero on failure
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-    
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("-- types int")
-    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + id
-               + " AND (expiry_time > datetime('now') OR NOT expires)")
-    count, = cu.fetchone()
-
-    if not count:
-        cx.close()
-        return -1
-
-    if expiry:
-        expires = 1
-        expiry_ts = "datetime('now', '" + str(expiry) + " seconds')"
-    else:
-        expires = 0
-        expiry_ts = "NULL"
-
-    cu.execute("UPDATE vdisks SET expires = " + str(expires)
-               + ", expiry_time = " + expiry_ts
-               + " WHERE (expiry_time > datetime('now') OR NOT expires)"
-               + " AND vdisk_id = " + id)
-
-    cx.commit()
-    cx.close()
-    
-    return 0
-
-
-def vd_delete(id):
-    """Deletes a Virtual Disk, making its extents available for future VDs.
-       id [string]   : identifier for the virtual disk to delete
-       returns [int] : 0 on success, -1 on failure (VD not found
-                       or already deleted)
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-    
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("-- types int")
-    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + id
-               + " AND (expiry_time > datetime('now') OR NOT expires)")
-    count, = cu.fetchone()
-
-    if not count:
-        cx.close()
-        return -1
-
-    cu.execute("UPDATE vdisks SET expires = 1, expiry_time = datetime('now')"
-               + " WHERE vdisk_id = " + id)
-
-    cx.commit()
-    cx.close()
-    
-    return 0
-
-
-def vd_freespace():
-    """Returns the amount of free space available for new virtual disks, in MB
-    returns [int] : free space for VDs in MB
-    """
-
-    if not os.path.isfile(VD_DB_FILE):
-        __vd_no_database()
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("-- types int")
-
-    cu.execute("""SELECT SUM(extent_size)
-                  FROM vdisks NATURAL JOIN vdisk_extents
-                                           NATURAL JOIN vdisk_part
-                  WHERE expiry_time <= datetime('now') AND expires""")
-
-    sum, = cu.fetchone()
-
-    cx.close()
-
-    return sum / VBD_SECTORS_PER_MB
-
-
-def vd_init_db(path):
-    """Initialise the VD SQLite database
-    path [string]: path to the SQLite database file
-    """
-
-    cx = sqlite.connect(path)
-    cu = cx.cursor()
-
-    cu.execute(
-        """CREATE TABLE vdisk_extents
-                           ( vdisk_extent_no INT,
-                             vdisk_id INT,
-                             part_id INT,
-                             part_extent_no INT )
-        """)
-
-    cu.execute(
-        """CREATE TABLE vdisk_part
-                           ( part_id INT,
-                             partition VARCHAR,
-                             extent_size INT )
-        """)
-
-    cu.execute(
-        """CREATE TABLE vdisks
-                           ( vdisk_id INT,
-                             size INT,
-                             expires BOOLEAN,
-                             expiry_time TIMESTAMP )
-        """)
-
-
-    cu.execute(
-        """INSERT INTO vdisks ( vdisk_id, size, expires, expiry_time )
-                       VALUES ( 0,        0,    1,       datetime('now') )
-        """)
-
-    cx.commit()
-    cx.close()
-
-    VD_DB_FILE = path
-
-
-
-def vd_cp_to_file(vdisk_id,filename):
-    """Writes the contents of a specified vdisk out into a disk file, leaving
-    the original copy in the virtual disk pool."""
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    extents = vd_lookup(vdisk_id)
-
-    if not extents:
-        return -1
-    
-    file_idx = 0 # index into source file, in sectors
-
-    for i in extents:
-        cu.execute("""SELECT partition, extent_size FROM vdisk_part
-                      WHERE part_id =  """ + str(i['part_device']))
-
-        (partition, extent_size) = cu.fetchone()
-
-        os.system("dd bs=1b if=" + partition + " of=" + filename
-                  + " skip=" + str(i['part_start_sector'])
-                  + " seek=" + str(file_idx)
-                  + " count=" + str(i['nr_sectors'])
-                  + " > /dev/null")
-
-        file_idx += i['nr_sectors']
-
-    cx.close()
-
-    return 0 # should return -1 if something breaks
-    
-
-def vd_mv_to_file(vdisk_id,filename):
-    """Writes a vdisk out into a disk file and frees the space originally
-    taken within the virtual disk pool.
-    vdisk_id [string]: ID of the vdisk to write out
-    filename [string]: file to write vdisk contents out to
-    returns [int]: zero on success, nonzero on failure
-    """
-
-    if vd_cp_to_file(vdisk_id,filename):
-        return -1
-
-    if vd_delete(vdisk_id):
-        return -1
-
-    return 0
-
-
-def vd_read_from_file(filename,expiry):
-    """Reads the contents of a file directly into a vdisk, which is
-    automatically allocated to fit.
-    filename [string]: file to read disk contents from
-    returns [string] : vdisk ID for the destination vdisk
-    """
-
-    size_bytes = os.stat(filename).st_size
-
-    (size_mb,leftover) =  divmod(size_bytes,1048580) # size in megabytes
-    if leftover > 0: size_mb += 1 # round up if not an exact number of MB
-
-    vdisk_id = vd_create(size_mb, expiry)
-
-    if vdisk_id < 0:
-        return -1
-
-    cx = sqlite.connect(VD_DB_FILE)
-    cu = cx.cursor()
-
-    cu.execute("""SELECT partition, extent_size, part_extent_no
-                  FROM vdisk_part NATURAL JOIN vdisk_extents
-                  WHERE vdisk_id =  """ + vdisk_id + """
-                  ORDER BY vdisk_extent_no ASC""")
-
-    extents = cu.fetchall()
-
-    size_sectors = size_mb * VBD_SECTORS_PER_MB # for feeding to dd
-
-    file_idx = 0 # index into source file, in sectors
-
-    def write_extent_to_vd((partition, extent_size, part_extent_no),
-                           file_idx, filename):
-        """Write an extent out to disk and update file_idx"""
-
-        os.system("dd bs=512 if=" + filename + " of=" + partition
-                  + " skip=" + str(file_idx)
-                  + " seek=" + str(part_extent_no * extent_size)
-                  + " count=" + str(min(extent_size, size_sectors - file_idx))
-                  + " > /dev/null")
-
-        return extent_size
-
-    for i in extents:
-        file_idx += write_extent_to_vd(i, file_idx, filename)
-
-    cx.close()
-
-    return vdisk_id
-    
-
-
-
-def vd_extents_validate(new_extents, new_writeable, safety=VBD_SAFETY_RR):
-    """Validate the extents against the existing extents.
-    Complains if the list supplied clashes against the extents that
-    are already in use in the system.
-    new_extents [list of dicts]: list of new extents, as dicts
-    new_writeable [int]: 1 if they are to be writeable, 0 otherwise
-    returns [int]: either the expertise level of the mapping if it doesn't
-                   exceed VBD_EXPERT_MODE or -1 if it does (error)
-    """
-
-    import Xc # this is only needed in this function
-
-    xc = Xc.new()
-
-    ##### Probe for explicitly created virtual disks and build a list
-    ##### of extents for comparison with the ones that are being added
-
-    probe = xc.vbd_probe()
-
-    old_extents = [] # this will hold a list of all existing extents and
-                     # their writeable status, as a list of (device,
-                     # start, size, writeable?) tuples
-
-    for vbd in probe:
-        this_vbd_extents = xc.vbd_getextents(vbd['dom'],vbd['vbd'])
-        for vbd_ext in this_vbd_extents:
-            vbd_ext['writeable'] = vbd['writeable']
-            old_extents.append(vbd_ext)
-            
-    ##### Now scan /proc/mounts for compile a list of extents corresponding to
-    ##### any devices mounted in DOM0.  This list is added on to old_extents
-
-    regexp = re.compile("/dev/(\S*) \S* \S* (..).*")
-    fd = open('/proc/mounts', "r")
-
-    while True:
-        line = readline(fd)
-        if not line: # if we've run out of lines then stop reading
-            break
-        
-        m = regexp.match(line)
-
-        # if the regexp didn't match then it's probably a line we don't
-        # care about - skip to next line
-        if not m:
-            continue
-
-        # lookup the device
-        ext_list = lookup_raw_partn(m.group(1))
-
-        # if lookup failed, skip to next mounted device
-        if not ext_list:
-            continue
-
-        # set a writeable flag as appropriate
-        for ext in ext_list:
-            ext['writeable'] = m.group(2) == 'rw'
-
-        # now we've got here, the contents of ext_list are in a
-        # suitable format to be added onto the old_extents list, ready
-        # for checking against the new extents
-
-        old_extents.extend(ext_list)
-
-    fd.close() # close /proc/mounts
-
-    ##### By this point, old_extents contains a list of extents, in
-    ##### dictionary format corresponding to every extent of physical
-    ##### disk that's either part of an explicitly created VBD, or is
-    ##### mounted under DOM0.  We now check these extents against the
-    ##### proposed additions in new_extents, to see if a conflict will
-    ##### happen if they are added with write status new_writeable
-
-    level = 0 # this'll accumulate the max warning level
-
-    # Search for clashes between the new extents and the old ones
-    # Takes time O(len(new_extents) * len(old_extents))
-    for new_ext in new_extents:
-        for old_ext in old_extents:
-            if(new_ext['device'] == old_ext['device']):
-
-                new_ext_start = new_ext['start_sector']
-                new_ext_end = new_ext_start + new_ext['nr_sectors'] - 1
-                
-                old_ext_start = old_ext['start_sector']
-                old_ext_end = old_ext_start + old_ext['nr_sectors'] - 1
-                
-                if((old_ext_start <= new_ext_start <= old_ext_end) or
-                   (old_ext_start <= new_ext_end <= old_ext_end)):
-                    if (not old_ext['writeable']) and new_writeable:
-                        level = max(1,level)
-                    elif old_ext['writeable'] and (not new_writeable):
-                        level = max(1,level)
-                    elif old_ext['writeable'] and new_writeable:
-                        level = max(2,level)
-
-
-    ##### level now holds the warning level incurred by the current
-    ##### VBD setup and we complain appropriately to the user
-
-
-    if level == 1:
-        print >> sys.stderr, """Warning: one or more hard disk extents
-         writeable by one domain are also readable by another."""
-    elif level == 2:
-        print >> sys.stderr, """Warning: one or more hard disk extents are
-         writeable by two or more domains simultaneously."""
-
-    if level > safety:
-        print >> sys.stderr, """ERROR: This kind of disk sharing is not allowed
-        at the current safety level (%d).""" % safety
-        level = -1
-
-    return level
-
index 1d67a843ef2bf53cac001cd86b5a0649479b80d9..03f3f1e25c80f3f992df57bb07b7482ae739bce9 100644 (file)
@@ -2,7 +2,7 @@
 from distutils.core import setup, Extension
 import sys
 
-modules = [ 'xenctl.console_client', 'xenctl.utils', 'xenctl.ip' , 'xenctl.vdisk' ]
+modules = [ 'xenctl.console_client', 'xenctl.utils', 'xenctl.ip' ]
 
 # We need the 'tempfile' module from Python 2.3. We install this ourselves
 # if the installed Python is older than 2.3.
index 60e207da651f8e5e2c137324eb929921d97aed28..9f7e143639dc7043068bdad048a00ac7eb766a97 100644 (file)
@@ -49,18 +49,28 @@ class XendDomain:
     def initial_refresh(self):
         """Refresh initial domain info from domain_db.
         """
+        print "initial_refresh> db=", self.domain_db.values()
         domlist = xc.domain_getinfo()
+        print "doms=", domlist
         doms = {}
         for d in domlist:
             domid = str(d['dom'])
             doms[domid] = d
         for config in self.domain_db.values():
             domid = int(sxp.child_value(config, 'id'))
+            print "dom=", domid, "config=", config
             if domid in doms:
+                print "dom=", domid, "new"
                 self._new_domain(config)
             else:
+                print "dom=", domid, "del"
                 self._delete_domain(domid)
+        print "doms:"
+        for d in self.domain.values(): print d
+        print "refresh..."
         self.refresh()
+        print "doms:"
+        for d in self.domain.values(): print d
 
     def sync(self):
         """Sync domain db to disk.
@@ -132,7 +142,7 @@ class XendDomain:
                 image = None
                 newinfo = XendDomainInfo.XendDomainInfo(
                     config, d['dom'], d['name'], d['mem_kb']/1024, image)
-                self._add_domain(id, newinfo)
+                self._add_domain(newinfo.id, newinfo)
         # Remove entries for domains that no longer exist.
         for d in self.domain.values():
             dominfo = doms.get(d.id)
@@ -319,18 +329,18 @@ class XendDomain:
                 return v
         return None
 
-    def domain_vbd_add(self, dom, uname, dev, mode):
-        dom = int(dom)
-        vbd = vm.make_disk(dom, uname, dev, mode)
-        return vbd
-
-    def domain_vbd_remove(self, dom, dev):
-        dom = int(dom)
-        vbd = xenctl.vdisk.blkdev_name_to_number(dev)
-        if vbd < 0: return vbd
-        err = xc.vbd_destroy(dom, vbd)
-        if err < 0: return err
-        return vbd
+##     def domain_vbd_add(self, dom, uname, dev, mode):
+##         dom = int(dom)
+##         vbd = vm.make_disk(dom, uname, dev, mode)
+##         return vbd
+
+##     def domain_vbd_remove(self, dom, dev):
+##         dom = int(dom)
+##         vbd = xenctl.vdisk.blkdev_name_to_number(dev)
+##         if vbd < 0: return vbd
+##         err = xc.vbd_destroy(dom, vbd)
+##         if err < 0: return err
+##         return vbd
 
     def domain_shadow_control(self, dom, op):
         dom = int(dom)
index efa56d7f32dab37b20777713861d0836c4baa483..84def89b81b14bc65d06658fd66fbd0fc1eea353 100644 (file)
@@ -9,6 +9,8 @@ Author: Mike Wray <mike.wray@hpl.hp.com>
 
 """
 
+import string
+import re
 import sys
 import os
 
@@ -17,7 +19,6 @@ from twisted.internet import defer
 import Xc; xc = Xc.new()
 
 import xenctl.ip
-import xenctl.vdisk
 
 import sxp
 
@@ -27,6 +28,24 @@ xendConsole = XendConsole.instance()
 import server.SrvConsoleServer
 xend = server.SrvConsoleServer.instance()
 
+def readlines(fd):
+    """Version of readlines safe against EINTR.
+    """
+    import errno
+    
+    lines = []
+    while 1:
+        try:
+            line = fd.readline()
+        except IOError, ex:
+            if ex.errno == errno.EINTR:
+                continue
+            else:
+                raise
+        if line == '': break
+        lines.append(line)
+    return lines
+
 class VmError(ValueError):
     """Vm construction error."""
 
@@ -60,6 +79,7 @@ class XendDomainInfo:
         self.devices = {}
         self.configs = []
         self.info = None
+        self.ipaddrs = []
 
         #todo: state: running, suspended
         self.state = 'running'
@@ -127,6 +147,12 @@ class XendDomainInfo:
         return sxp.child_with_id(self.get_devices(type), id)
 
     def get_device_by_index(self, type, idx):
+        """Get the device with the given index.
+
+        idx       device index
+
+        returns  device or None
+        """
         dl = self.get_devices(type)
         if 0 <= idx < len(dl):
             return dl[idx]
@@ -163,48 +189,81 @@ class XendDomainInfo:
             print
         print "]"
 
-def safety_level(sharing):
-    if sharing == 'rw':
-        return xenctl.vdisk.VBD_SAFETY_RW
-    if sharing == 'ww':
-        return xenctl.vdisk.VBD_SAFETY_WW
-    return xenctl.vdisk.VBD_SAFETY_RR
-
-
-def make_disk_old(dom, uname, dev, mode, sharing):
-    writeable = ('w' in mode)
-    safety = safety_level(sharing)
-    vbd = xenctl.vdisk.blkdev_name_to_number(dev)
-    extents = xenctl.vdisk.lookup_disk_uname(uname)
-    if not extents:
-        raise VmError("vbd: Extents not found: uname=%s" % uname)
-
-    # check that setting up this VBD won't violate the sharing
-    # allowed by the current VBD expertise level
-    if xenctl.vdisk.vd_extents_validate(extents, writeable, safety=safety) < 0:
-        raise VmError("vbd: Extents invalid: uname=%s" % uname)
-            
-    if xc.vbd_create(dom=dom, vbd=vbd, writeable=writeable):
-        raise VmError("vbd: Creating device failed: dom=%d uname=%s vbd=%d mode=%s"
-                      % (dom, uname, vbdmode))
-
-    if xc.vbd_setextents(dom=dom, vbd=vbd, extents=extents):
-        raise VMError("vbd: Setting extents failed: dom=%d uname=%s vbd=%d"
-                      % (dom, uname, vbd))
-    return vbd
+def blkdev_name_to_number(name):
+    """Take the given textual block-device name (e.g., '/dev/sda1',
+    'hda') and return the device number used by the OS. """
+
+    if not re.match( '/dev/', name ):
+        name = '/dev/' + name
+        
+    return os.stat(name).st_rdev
+
+def lookup_raw_partn(partition):
+    """Take the given block-device name (e.g., '/dev/sda1', 'hda')
+    and return a dictionary { device, start_sector,
+    nr_sectors, type }
+        device:       Device number of the given partition
+        start_sector: Index of first sector of the partition
+        nr_sectors:   Number of sectors comprising this partition
+        type:         'Disk' or identifying name for partition type
+    """
+
+    if not re.match( '/dev/', partition ):
+        partition = '/dev/' + partition
+
+    drive = re.split( '[0-9]', partition )[0]
+
+    if drive == partition:
+        fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' )
+        line = readline(fd)
+        if line:
+            return [ { 'device' : blkdev_name_to_number(drive),
+                       'start_sector' : long(0),
+                       'nr_sectors' : long(line) * 2,
+                       'type' : 'Disk' } ]
+        return None
+
+    # determine position on disk
+    fd = os.popen( '/sbin/sfdisk -d ' + drive + ' 2>/dev/null' )
+
+    #['/dev/sda3 : start= 16948575, size=16836120, Id=83, bootable\012']
+    lines = readlines(fd)
+    for line in lines:
+        m = re.search( '^' + partition + '\s*: start=\s*([0-9]+), ' +
+                       'size=\s*([0-9]+), Id=\s*(\S+).*$', line)
+        if m:
+            return [ { 'device' : blkdev_name_to_number(drive),
+                       'start_sector' : long(m.group(1)),
+                       'nr_sectors' : long(m.group(2)),
+                       'type' : m.group(3) } ]
+    
+    return None
+
+def lookup_disk_uname( uname ):
+    """Lookup a list of segments for a physical device.
+    uname [string]:  name of the device in the format \'phy:dev\' for a physical device
+    returns [list of dicts]: list of extents that make up the named device
+    """
+    ( type, d_name ) = string.split( uname, ':' )
+
+    if type == "phy":
+        segments = lookup_raw_partn( d_name )
+    else:
+        segments = None
+    return segments
 
 def make_disk(dom, uname, dev, mode, sharing):
     """Create a virtual disk device for a domain.
 
     @returns Deferred
     """
-    segments = xenctl.vdisk.lookup_disk_uname(uname)
+    segments = lookup_disk_uname(uname)
     if not segments:
         raise VmError("vbd: Segments not found: uname=%s" % uname)
     if len(segments) > 1:
         raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
     segment = segments[0]
-    vdev = xenctl.vdisk.blkdev_name_to_number(dev)
+    vdev = blkdev_name_to_number(dev)
     ctrl = xend.blkif_create(dom)
     
     def fn(ctrl):
@@ -212,13 +271,6 @@ def make_disk(dom, uname, dev, mode, sharing):
     ctrl.addCallback(fn)
     return ctrl
         
-def make_vif_old(dom, vif, vmac, vnet):
-    return # todo: Not supported yet.
-    err = xc.vif_setinfo(dom=dom, vif=vif, vmac=vmac, vnet=vnet)
-    if err < 0:
-        raise VmError('vnet: Error %d setting vif mac dom=%d vif=%d vmac=%s vnet=%d' %
-                        (err, dom, vif, vmac, vnet))
-
 def make_vif(dom, vif, vmac):
     """Create a virtual network device for a domain.
 
@@ -230,8 +282,10 @@ def make_vif(dom, vif, vmac):
     return d
 
 def vif_up(iplist):
-    #todo: Need a better way.
-    # send an unsolicited ARP reply for all non link-local IPs
+    """send an unsolicited ARP reply for all non link-local IP addresses.
+
+    iplist IP addresses
+    """
 
     IP_NONLOCAL_BIND = '/proc/sys/net/ipv4/ip_nonlocal_bind'
     
@@ -260,6 +314,18 @@ def vif_up(iplist):
         if not nlb: set_ip_nonlocal_bind(0)
 
 def xen_domain_create(config, ostype, name, memory, kernel, ramdisk, cmdline, vifs_n):
+    """Create a domain. Builds the image but does not configure it.
+
+    config  configuration
+    ostype  OS type
+    name    domain name
+    memory  domain memory (MB)
+    kernel  kernel image
+    ramdisk kernel ramdisk
+    cmdline kernel commandline
+    vifs_n  number of network interfaces
+    returns vm
+    """
     if not os.path.isfile(kernel):
         raise VmError('Kernel image does not exist: %s' % kernel)
     if ramdisk and not os.path.isfile(ramdisk):
@@ -380,11 +446,22 @@ def vm_create(config):
     return deferred
 
 def vm_restore(src, config, progress=0):
+    """Restore a VM.
+
+    src      saved state to restore
+    config   configuration
+    progress progress reporting flag
+    returns  deferred
+    raises   VmError for invalid configuration
+    """
     ostype = "linux" #todo set from config
     restorefn = getattr(xc, "%s_restore" % ostype)
     dom = restorefn(state_file=src, progress=progress)
     if dom < 0: return dom
     deferred = dom_configure(dom, config)
+    def vifs_cb(val, vm):
+        vif_up(vm.ipaddrs)
+    deferred.addCallback(vifs_cb, vm)
     return deferred
     
 def dom_get(dom):
@@ -394,6 +471,12 @@ def dom_get(dom):
     return None
     
 def dom_configure(dom, config):
+    """Configure a domain.
+
+    dom    domain id
+    config configuration
+    returns deferred
+    """
     d = dom_get(dom)
     if not d:
         raise VMError("Domain not found: %d" % dom)
@@ -628,6 +711,7 @@ def vm_field_vfr(vm, config, val, index):
     # Get the rules and add them.
     # (vfr (vif (id foo) (ip x.x.x.x)) ... ) 
     list = sxp.children(val, 'vif')
+    ipaddrs = []
     for v in list:
         id = sxp.child_value(v, 'id')
         if id is None:
@@ -640,9 +724,11 @@ def vm_field_vfr(vm, config, val, index):
         ip = sxp.child_value(v, 'ip')
         if not ip:
             raise VmError('vfr: missing ip address')
+        ipaddrs.append(ip);
         #Don't do this in new i/o model.
         #print 'vm_field_vfr> add rule', 'dom=', vm.dom, 'vif=', vif, 'ip=', ip
         #xenctl.ip.setup_vfr_rules_for_vif(vm.dom, vif, ip)
+    vm.ipaddrs = ipaddrs
 
 def vnet_bridge(vnet, vmac, dom, idx):
     """Add the device for the vif to the bridge for its vnet.
diff --git a/tools/xenmgr/lib/XendVdisk.py b/tools/xenmgr/lib/XendVdisk.py
deleted file mode 100644 (file)
index 241d29b..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-"""Handler for vdisk operations.
-
-"""
-
-import os
-import os.path
-
-from xenctl import vdisk
-    
-import sxp
-
-class XendVdiskInfo:
-
-    def __init__(self, info):
-        self.info = info
-        self.id = info['vdisk_id']
-
-    def __str__(self):
-        return ("vdisk id=%(vdisk_id)s size=%(size)d expires=%(expires)d expiry_time=%(expiry_time)d"
-                % self.info)
-
-    def sxpr(self):
-        val = ['vdisk']
-        for (k,v) in self.info.items():
-            val.append([k, str(v)])
-        return val     
-
-class XendVdisk:
-    """Index of all vdisks. Singleton.
-    """
-
-    dbpath = "vdisk"
-
-    def __init__(self):
-        # Table of vdisk info indexed by vdisk id.
-        self.vdisk = {}
-        if not os.path.isfile(vdisk.VD_DB_FILE):
-            vdisk.vd_init_db(vdisk.VD_DB_FILE)
-        self.vdisk_refresh()
-
-    def vdisk_refresh(self):
-        # vdisk = {vdisk_id, size, expires, expiry_time}
-        try:
-            vdisks = vdisk.vd_list()
-        except:
-            vdisks = []
-        for vdisk in vdisks:
-            vdiskinfo = XendVdiskInfo(vdisk)
-            self.vdisk[vdiskinfo.id] = vdiskinfo
-
-    def vdisk_ls(self):
-        """List all vdisk ids.
-        """
-        return self.vdisk.keys()
-
-    def vdisks(self):
-        return self.vdisk.values()
-    
-    def vdisk_get(self, id):
-        """Get a vdisk.
-
-        id     vdisk id
-        """
-        return self.vdisk.get(id)
-
-    def vdisk_create(self, info):
-        """Create a vdisk.
-
-        info   config
-        """
-        # Need to configure for real.
-        # vdisk.vd_create(size, expiry)
-
-    def vdisk_configure(self, info):
-        """Configure a vdisk.
-        id     vdisk id
-        info   config
-        """
-        # Need to configure for real.
-        # Make bigger: vdisk.vd_enlarge(id, extra_size)
-        # Update expiry time: vdisk.vd_refresh(id, expiry)
-        # Try to recover an expired vdisk : vdisk.vd_undelete(id, expiry)
-        
-
-    def vdisk_delete(self, id):
-        """Delete a vdisk.
-
-        id     vdisk id
-        """
-        # Need to delete vdisk for real. What if fails?
-        del self.vdisk[id]
-        vdisk.vd_delete(id)
-
-    # def vdisk_copy: copy contents to file, vdisk still exists
-    # def vdisk_export: copy contents to file then delete the vdisk 
-    # def vdisk_import: create a vdisk from a file
-    # def vdisk_space: space left for new vdisks
-
-    # def vdisk_recover: recover an expired vdisk
-
-    # def vdisk_init_partition: setup a physical partition for vdisks
-
-def instance():
-    global inst
-    try:
-        inst
-    except:
-        inst = XendVdisk()
-    return inst
index b002d2cf76394e718632a60e8766d29be0d5a47d..6256d83a4ba5985caab5c2b3decf8ca5fdab8363 100644 (file)
@@ -17,7 +17,6 @@ class SrvRoot(SrvDir):
         ('domain',  'SrvDomainDir'  ),
         ('console', 'SrvConsoleDir' ),
         ('event',   'SrvEventDir'   ),
-        ('vdisk',   'SrvVdiskDir'   ),
         ('device',  'SrvDeviceDir'  ),
         ('vnet',    'SrvVnetDir'    ),
         ]
diff --git a/tools/xenmgr/lib/server/SrvVdisk.py b/tools/xenmgr/lib/server/SrvVdisk.py
deleted file mode 100644 (file)
index 4200b9b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-from xenmgr import XendVdisk
-from SrvVdiskDir import SrvVdiskDir
-
-class SrvVdisk(SrvDir):
-    """A virtual disk.
-    """
-
-    def __init__(self):
-        SrvDir.__init__(self)
-        self.xvdisk = XendVdisk.instance()
diff --git a/tools/xenmgr/lib/server/SrvVdiskDir.py b/tools/xenmgr/lib/server/SrvVdiskDir.py
deleted file mode 100644 (file)
index a6a9e55..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-from xenmgr import XendVdisk
-from SrvDir import SrvDir
-
-class SrvVdiskDir(SrvDir):
-    """Virtual disk directory.
-    """
-
-    def __init__(self):
-        SrvDir.__init__(self)
-        self.xvdisk = XendVdisk.instance()
-
-    def vdisk(self, x):
-        val = None
-        try:
-            dom = self.xvdisk.vdisk_get(x)
-            val = SrvVdisk(dom)
-        except KeyError:
-            pass
-        return val
-
-    def get(self, x):
-        v = SrvDir.get(self, x)
-        if v is not None:
-            return v
-        v = self.vdisk(x)
-        return v